    using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using DG.Tweening;
using GameManager.GamePlay;
using Unity.VisualScripting;
using UnityEngine;

public class BiliardGameManager : MonoBehaviour
{
    /// <summary>
    /// 杂项，于台球无关
    /// </summary>
    private float LastWidth;
    private float LastHeight;

    public static BiliardGameManager instance;

    [Header("力量系数")]
    public float PowerFactor;

    [Header("球杆")]
    public GameObject CueRotGameObject;
    public GameObject CuePosGameObject;
    [Header("球杆位置距离白球的距离")]
    public float cuePositionDistance;
    [Header("球杆高度")]
    public float CueHeight;

    [Header("白球")]
    public WhiteBall whiteBall;
    [Header("目标球")]
    public List<TargetBall> targetBalls;

    public GamePlayInfo GamePlayInfo;

    public GuideLineScripts guideLineScripts;

    public PowerValueImage powerValueImage;

    public CueAngleScripts cueAngleScripts;

    public UIGold uigold;

    public UIEnd uiend;

    //球杆初始位置
    private Vector3 InitCueGameObjectPos;
    [Header("球杆拖动时可移动范围系数")]
    public float DragDistance;

    [Header("靶心")]
    public Animator baxin;
    [Header("靶心图片")]
    public List<SpriteRenderer> BaxinspriteRenderers = new List<SpriteRenderer>();
    [Header("得分位置")]
    public List<float> ScoreDistance = new List<float>();
    [Header("得分列表")]
    public List<int> TargetScore = new List<int>();
    [Header("几次开球时的白球位置")]
    public List<Vector3> whiteBallInitPos = new List<Vector3>();
    [Header("几次开球时的目标球位置")]
    // [SerializeField]
    // public List<List<Vector3>> targetBallInitPos = new List<List<Vector3>>();
    // public Vector3[][] targetBallInitPos = new Vector3[3][];
    [SerializeField]
    public List<Vector3Row> targetBallInitPos;

    public List<Vector3> BaxinPos = new List<Vector3>();

    public int CurrentScore;

    private bool IsPot; //是否在击球中

    // private bool IsFirstShot;

    public int ShotIndex;
    public int FailCount; //失败次数

    public AudioSource BGM;
    public AudioSource Win;
    public AudioSource Success;
    public AudioSource ShotAudioSource;

    public RectTransform PowerBG; //PowerBG适配！
    public RectTransform tutoriseRect;

    private bool IsFirstClick;

    private readonly Vector3 LandscapeModeInitPos = new Vector3(0f,1.05f,-1.58f);
    private readonly Vector3 LandscapeModeMovePos = new Vector3(-0.001f,1.1f,-0.4f);
    private readonly Vector3 LandscapeModeRot = new Vector3(33.5f,0f,0); 

    private readonly Vector3 HorizontalModeInitPos = new Vector3(0f,1.05f,-1.58f);
    private readonly Vector3 HorizontalModeMovePos = new Vector3(-0.001f,1.1f,-0.4f);
    private readonly Vector3 HorizontalModeRot = new Vector3(33.5f,0f,0);

    private readonly Vector3 PotPos = new Vector3(0,2.2f,-1.34f);
    private readonly Vector3 PotRot = new Vector3(60,0,0);

    private Vector3 CameraToWhiteBallPos = new Vector3();

    void Awake()
    {
        instance = this;
    }
    // Start is called before the first frame update
    void Start()
    {
        CameraToWhiteBallPos = Camera.main.transform.position - whiteBall.transform.position;
        
        Luna.Unity.LifeCycle.OnUnmute += () =>
        {
            AudioListener.volume = 1;
        };

        Luna.Unity.LifeCycle.OnMute += () =>
        {
            AudioListener.volume = 0;
        };

        baxin.gameObject.SetActive(false);

        ShotIndex = 0;

        whiteBall.transform.position = whiteBallInitPos[ShotIndex];
        for (int i=0;i<targetBallInitPos[0].row.Count;i++) {
            targetBalls[i].transform.position = targetBallInitPos[0].row[i];
        }
        for (int i = 1; i < targetBalls.Count; i++)
        {
            targetBalls[i].gameObject.SetActive(false);
        }
        baxin.transform.position = BaxinPos[ShotIndex];

        RestartCuePosition();
        RestartCueRotation();
        guideLineScripts.Init();
        powerValueImage.PowerDragAction += CueGameObjectDrag;
        powerValueImage.PowerUpAction += CueGameObjectUp;
        powerValueImage.PowerDownAction += CueGameObjectDown;

        EventManager.Instance.Subscribe(PotCompleteEvent.EventId, PotCompleteCallBack);

        Init();

        LastWidth = Screen.width;
        LastHeight = Screen.height;
        if (Screen.width > Screen.height) //横屏
        {
            Camera.main.transform.position = LandscapeModeInitPos;
            Camera.main.transform.localEulerAngles = LandscapeModeRot;
            PowerBG.anchoredPosition = new Vector2(100, 0);
        }
        else //竖屏
        {
            Camera.main.transform.position = HorizontalModeInitPos;
            Camera.main.transform.localEulerAngles = HorizontalModeRot;
            PowerBG.anchoredPosition = new Vector2(30, 0);
        }

    }

    // Update is called once per frame
    void Update()
    {

        if (!IsFirstClick && Input.GetMouseButtonDown(0))
        {
            IsFirstClick = true;
            BGM.Play();
        }

        if (LastWidth != Screen.width || LastHeight != Screen.height) //横屏
        {
            LastWidth = Screen.width;
            LastHeight = Screen.height;

            if (Screen.width > Screen.height)
            {
                Camera.main.transform.position = LandscapeModeInitPos;
                Camera.main.transform.localEulerAngles = LandscapeModeRot;
                PowerBG.anchoredPosition = new Vector2(100, 0);
            }
            else
            {
                Camera.main.transform.position = HorizontalModeInitPos;
                Camera.main.transform.localEulerAngles = HorizontalModeRot;
                PowerBG.anchoredPosition = new Vector2(30, 0);
            }

            EventManager.Instance.Fire(this, new ScreenChangeEvent());
        }

        if (IsPot) {
            foreach (SpriteRenderer spriteRenderer in BaxinspriteRenderers)
            {
                spriteRenderer.color = new Color(1, 1, 1, 0.5f);
            }

            for (int i = 0; i < targetBalls.Count; i++)
            {
                if (!targetBalls[i].gameObject.activeSelf)
                {
                    continue;
                }
                bool IsGetScore = false;// 是否已经有球再其中了！
                for (int j = 0; j < ScoreDistance.Count; j++)
                {
                    float distance = Vector3.Distance(baxin.transform.position, targetBalls[i].transform.position);
                    if (distance < ScoreDistance[j]) //得分！
                    {
                        BaxinspriteRenderers[j].color = new Color(1, 1, 1, 1);
                        uigold.RefreshBallGolds(i, targetBalls[i].InitGold * TargetScore[j]);
                        IsGetScore = true;
                        break;
                    }
                }
                if (!IsGetScore)
                {
                    uigold.RefreshBallGolds(i, targetBalls[i].InitGold);
                    targetBalls[i].CloseXifU();
                }
                else
                {
                    Vector3 directionToTarget = (baxin.transform.position - targetBalls[i].transform.position).normalized;
                    float dotProduct = Vector3.Dot(targetBalls[i]._rigidbody.velocity, directionToTarget);
                    if (dotProduct < 0) {
                        targetBalls[i].OpenXifu();
                     
                    }
                }
            }
        }
    }

    async void FixedUpdate()
    {
        if (IsPot)
        {

            foreach (TargetBall targetBall in targetBalls)
            {
                if (targetBall._rigidbody.velocity.magnitude <= 0.05f)
                {

                }
                else
                {
                    //有一个球的速度不够格，则直接跳出，永远判断为此球暂时未结束，不执行后续逻辑
                    return;
                }
            }
            float WhiteBallCurrentSpeed = whiteBall._rigidbody.velocity.magnitude;
            if (WhiteBallCurrentSpeed <= 0.05f)
            {
                foreach (TargetBall targetBall in targetBalls)
                {
                    targetBall._rigidbody.velocity = Vector3.zero;
                }
                whiteBall._rigidbody.velocity = Vector3.zero;
                PotCompleteEvent potCompleteEvent = new PotCompleteEvent();
                EventManager.Instance.Fire(this, potCompleteEvent);
                IsPot = false;
                // if (ShotIndex == 0) {
                ShotIndex += 1;
                // }
                await Balance();
                await Task.Delay(1000);
                Debug.LogError(ShotIndex);
                if (ShotIndex == 4)
                {
                    await Task.Delay(1000);
                    uiend.gameObject.SetActive(true);
                    Win.Play();
                }
                else
                {
                    await Task.Delay(100);
                    Debug.LogError("移动球");

                    if (ShotIndex == 1)
                    {
                        TrailRenderer whiteballTrail = whiteBall.GetComponent<TrailRenderer>();
                        whiteballTrail.Clear();
                        whiteballTrail.time = 0;
                        whiteBall._rigidbody.MovePosition(whiteBallInitPos[ShotIndex]);
                        // whiteballTrail.time = 0.2f; 
                        // whiteBall.GetComponent<TrailRenderer>().enabled = true;
                        for (int i = 0; i < targetBalls.Count; i++)
                        {
                            targetBalls[i].gameObject.SetActive(true);
                            targetBalls[i].GoldObject.gameObject.SetActive(true);
                            uigold.BallGolds[i].gameObject.SetActive(true);
                            TrailRenderer targetballTrail = targetBalls[i].GetComponent<TrailRenderer>();
                            targetballTrail.Clear();
                            targetballTrail.time = 0;
                            targetBalls[i]._rigidbody.MovePosition(targetBallInitPos[ShotIndex].row[i]);
                                                        // targetballTrail.time = 0.2f;
                            uigold.RefreshBallGolds(i, targetBalls[i].InitGold);
                        }
                        
                        baxin.transform.position = BaxinPos[ShotIndex];
                        baxin.enabled = true;

                        // CurrentScore = 0;
                        // uigold.RefreshProgress();
                        uigold.Effect.gameObject.SetActive(false);
                        baxin.Play("靶心弹跳动画");
                    }
                    else
                    {
                        
                    }
                    // baxin.SetTrigger("Move");
                    await Task.Delay(3000);
                    baxin.enabled = false;
                    OpenShotState();
                    
                }
            }
            else
            {
                return;
            }
        }
    }

    public async Task Init()
    {
        CloseShotState();
        await Task.Delay(1000);

        if (Screen.width > Screen.height)
        {
            Camera.main.transform.DOMove(LandscapeModeMovePos, 0.3f).OnComplete(async () =>
            {
                baxin.gameObject.SetActive(true);
                // baxin.SetTrigger("tantiao");
                await Task.Delay(1000);
                baxin.SetTrigger("Init");
            });
        }
        else
        {
            Camera.main.transform.DOMove(HorizontalModeMovePos, 0.3f).OnComplete(async () =>
            {
                baxin.gameObject.SetActive(true);
                // baxin.SetTrigger("tantiao");
                await Task.Delay(1000);
                baxin.SetTrigger("Init");
            });
        }


        await Task.Delay(2000);
        baxin.enabled = false;
        Camera.main.transform.DOMoveZ(0f, 0.3f);
        if (Screen.width > Screen.height)
        {
            Camera.main.transform.DOMove(LandscapeModeInitPos, 0.3f).OnComplete(() =>
            {
                OpenShotState();
            });
        }
        else
        {
            // Camera.main.DOOrthoSize(0.85f, 0.3f).OnComplete(() =>
            // {
            //     OpenShotState();
            // });

            Camera.main.transform.DOMove(HorizontalModeInitPos, 0.3f).OnComplete(() =>
            {
                OpenShotState();
            });
        }

    }

    /// <summary>
    /// 重置球杆位置
    /// </summary>
    public void RestartCuePosition()
    {
        //这里使用CueRotGameObject是因为这里移动是世界坐标

        CueRotGameObject.transform.position = whiteBall.transform.position + (whiteBall.transform.position -
                                                targetBalls[0].transform.position).normalized * cuePositionDistance;
        // Debug.LogError((WhiteBall.transform.position - e.transform.position).normalized * cuePositionDistance);
        // Debug.DrawLine( e.transform.position,(WhiteBall.transform.position - e.transform.position).normalized * cuePositionDistance);
        CueRotGameObject.transform.position = new Vector3(CueRotGameObject.transform.position.x, CueHeight,
            CueRotGameObject.transform.position.z);
        CuePosGameObject.transform.localPosition = Vector3.zero;
    }

    /// <summary>
    /// 重置球杆旋转
    /// </summary>
    public void RestartCueRotation()
    {
        Vector3 whiteballpos = new Vector3(whiteBall.transform.position.x, CueHeight, whiteBall.transform.position.z);
        Vector3 direction = (whiteballpos - CueRotGameObject.transform.position).normalized;
        CueRotGameObject.transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
    }

    /// <summary>
    /// 当玩家拖动力量条时，球杆也需要跟着往后移动
    /// </summary>
    /// <param name="Power"></param>
    public void CueGameObjectDrag(float Power)
    {
        CuePosGameObject.transform.position = InitCueGameObjectPos -
                                                   CuePosGameObject.transform.forward.normalized *
                                                   DragDistance * Power;
        GamePlayInfo.Power = Power;
    }

    /// <summary>
    /// 当玩家松开拖动力量条时
    /// 1.球杆返回原处
    /// 2.球杆应该在白球移动期间消失，直到白球停下位置
    /// 3.发球！
    /// </summary>
    /// <param name="Power"></param>
    private async void CueGameObjectUp(float Power)
    {
        InitCueGameObjectPos = Vector3.zero;
        if (Power > 0)
        {
            //触发发球事件后，令力量值等于传进来的参数
            GamePlayInfo.Power = Power;
            RestartCuePosition();
            //发球
            ShotBallEvent shotBallEvent = new ShotBallEvent();
            EventManager.Instance.Fire(this, shotBallEvent);

            if (ShotIndex == 0)
            {
                GamePlayInfo.Power = 25f;
            }
            if (ShotIndex == 1) {
                // GamePlayInfo.Power = 200f;
            }

            ShotBallMethod();
            Camera.main.transform.DOMove(PotPos, 0.2f);
            Camera.main.transform.DORotate(PotRot, 0.2f);
            await Task.Delay(500);

            IsPot = true;
        }

    }

    /// <summary>
    /// 玩家按下力量条时候
    /// 记载当时的位置，接下来靠这个移动
    /// </summary>
    private void CueGameObjectDown()
    {
        InitCueGameObjectPos = CuePosGameObject.transform.position;
    }


    /// <summary>
    /// 发球
    /// </summary>
    private void ShotBallMethod()
    {
        float power = GamePlayInfo.Power;
        Vector3 ShotDirection = GamePlayInfo.ShotDirection;

        whiteBall._rigidbody.AddForceAtPosition(ShotDirection * power, whiteBall.transform.position);
        Debug.LogError(ShotDirection * power);
        // whiteBall._rigidbody.AddRelativeForce(ShotDirection * power, ForceMode.Impulse);
        CloseShotState();
        ShotAudioSource.Play(); 
    }

    /// <summary>
    /// 关闭射击状态
    /// </summary>
    public void CloseShotState()
    {
        powerValueImage.gameObject.transform.parent.parent.gameObject.SetActive(false);
        guideLineScripts.gameObject.SetActive(false);
        cueAngleScripts.gameObject.SetActive(false);
        CueRotGameObject.gameObject.SetActive(false);
    }

    /// <summary>
    /// 开启射击状态
    /// </summary>
    public void OpenShotState()
    {
        powerValueImage.gameObject.transform.parent.parent.gameObject.SetActive(true);
        guideLineScripts.gameObject.SetActive(true);
        if (ShotIndex != 0)
        {
            cueAngleScripts.gameObject.SetActive(true);
        }
        CueRotGameObject.gameObject.SetActive(true);
        RestartCuePosition();
        RestartCueRotation();
        // 基于白球的位置和球杆方向设置摄像机位置
        Vector3 cueDirection = (whiteBall.transform.position - targetBalls[0].transform.position).normalized;
        Vector3 cameraToWhiteBallPosXZ = new Vector3(CameraToWhiteBallPos.x, whiteBall.transform.position.y, CameraToWhiteBallPos.z);
        Vector3 cameraPosition = whiteBall.transform.position + cameraToWhiteBallPosXZ.magnitude * cueDirection;
        cameraPosition.y = CameraToWhiteBallPos.y + whiteBall.transform.position.y;
        // Camera.main.transform.position = cameraPosition;
        Camera.main.transform.DOMove(cameraPosition, 0.2f);

        // 计算相机需要旋转到的角度
        Vector3 directionToWhiteBall = (whiteBall.transform.position - cameraPosition).normalized;
        Quaternion targetRotation = Quaternion.LookRotation(directionToWhiteBall);

        // 使用DORotate平滑旋转到目标角度
        Camera.main.transform.DORotate(new Vector3(HorizontalModeRot.x, targetRotation.eulerAngles.y, 0), 0.2f);


        TrailRenderer whiteballTrail = whiteBall.GetComponent<TrailRenderer>();
        whiteballTrail.time = 0.3f;
                        
        for (int i = 0; i < targetBalls.Count; i++)
        {
            TrailRenderer targetballTrail = targetBalls[i].GetComponent<TrailRenderer>();
            targetballTrail.time = 0.3f;
        }
    }

    /// <summary>
    /// 结算
    /// </summary>
    /// <returns></returns>
    public async Task Balance()
    {
        int m_CurrentScore = CurrentScore;
        int targetscore = m_CurrentScore;
        for (int i = 0; i < targetBalls.Count; i++)
        {
            if(!targetBalls[i].gameObject.activeSelf){
                continue;
            }
            Vector3 targetpos = targetBalls[i].transform.position;
            targetpos = new Vector3(targetpos.x, baxin.transform.position.y, targetpos.z);
            float distance = Vector3.Distance(targetpos, baxin.gameObject.transform.position);
            int index = -1;
            for (int j = 0; j < ScoreDistance.Count; j++)
            {

                if (distance < ScoreDistance[j])
                {
                    index = j;
                    targetBalls[i].gameObject.SetActive(false);
                    targetBalls[i].GoldObject.gameObject.SetActive(false);
                    uigold.BallGolds[i].gameObject.SetActive(false);
                    break;
                }
            }



            if (index >= 0)
            {
                Success.Play();
                uigold.PlaySkeletonGraphic(index);

                // for (int k = 0; k < 10; k++)
                // {
                //     await Task.Delay(20);
                //     uigold.GetGold(baxin.gameObject);
                // }
                int AddScore = TargetScore[index] * targetBalls[i].InitGold;
                targetscore += AddScore;


                // DOTween.To(() => CurrentScore, x => CurrentScore = x, targetscore, 1f).SetEase(Ease.Linear).OnUpdate(() =>
                // {
                //     uigold.RefreshProgress();0
                // });

            }
            else
            {
                //没打中靶心，不会获得任何奖励,重置本球
            }
        }

        for (int i = 0; i < BaxinspriteRenderers.Count; i++)
        {
            BaxinspriteRenderers[i].color = new Color(1, 1, 1, 0.5f);
        }

        if (targetscore == m_CurrentScore)
        {
            //没有得分，不进行任何操纵
            return;
        }

        for (int k = 0; k < 10; k++)
        {
            await Task.Delay(20);
            uigold.GetGold(baxin.gameObject);
        }

        DOTween.To(() => CurrentScore, x => CurrentScore = x, targetscore, 1f).SetEase(Ease.Linear).OnUpdate(() =>
        {
            uigold.RefreshProgress();
        });
        


    }

    private void PotCompleteCallBack(object sender, EventArgs ea)
    {
        
    }
}
